package ar.com.bdf.ipharma.communications.serial;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import ar.com.bdf.ipharma.communications.RunnableLine;

public class SimpleRead implements Runnable, SerialPortEventListener {
	
	private Log log = LogFactory.getLog(SimpleRead.class);
	
	protected static CommPortIdentifier portId;
	protected static Enumeration<CommPortIdentifier> portList;

	protected InputStream inputStream;
	protected SerialPort serialPort;
	protected Thread readThread;
	protected RunnableLine runner;
	protected String portName;

	public SimpleRead(RunnableLine runner, String portName) {
		this.runner = runner;
		this.portName = portName;
		serialPortInitialization();
	}

	@SuppressWarnings("unchecked")
	private void serialPortInitialization() {
		portList = CommPortIdentifier.getPortIdentifiers();

		while (portList.hasMoreElements()) {
			portId = (CommPortIdentifier) portList.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				if (portId.getName().equals(portName)) {
					threadInitialization();
				}
			}
		}
	}

	private void threadInitialization() {
		log.info("------------  " + this.serialPort + "  ----------------");
		try {
			serialPort = HandlerPort.getInstance(portName);
			serialPort.addEventListener(this);
			serialPort.notifyOnDataAvailable(true);
			inputStream = serialPort.getInputStream();
		} catch (Exception e) {
			log.error(e);
		}
		readThread = new Thread(this);
		readThread.start();
		log.info("------------  Finalized Initialize Serial " + this.serialPort + "  ----------------");
	}

	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			log.error(e);
		}
	}

	public void serialEvent(SerialPortEvent event) {
		switch (event.getEventType()) {
		case SerialPortEvent.BI:
		case SerialPortEvent.OE:
		case SerialPortEvent.FE:
		case SerialPortEvent.PE:
		case SerialPortEvent.CD:
		case SerialPortEvent.CTS:
		case SerialPortEvent.DSR:
		case SerialPortEvent.RI:
		case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
			break;
		case SerialPortEvent.DATA_AVAILABLE:
			byte[] readBuffer = new byte[64];

			try {
				while (inputStream.available() > 0) {
					int numBytes = inputStream.read(readBuffer);
					runner.execute(new String(readBuffer, 0, numBytes));
				}
			} catch (IOException e) {
				log.error("serialEvent; Data Avaible", e);
			}
			break;
		}
	}
}
